home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / realloc.c < prev    next >
C/C++ Source or Header  |  1992-05-15  |  2KB  |  83 lines

  1. /* from the TOS GCC library */
  2. /* malloc, free, realloc: dynamic memory allocation */
  3. /* 5/2/92 sb -- modified for Heat-n-Serve C to accomodate its 16-bit size_t */
  4. /* 5/5/92 sb -- realloc() gets its own file to reduce library drag */
  5.  
  6. #include <stddef.h>    /* for size_t */
  7. #include <memory.h>
  8. #include <string.h>
  9. #include <assert.h>
  10. #include "lib.h"
  11.  
  12. void * _realloc(_r, n)
  13. void *_r;
  14. unsigned long n;
  15. {
  16.   struct mem_chunk *p, *q, *r = (struct mem_chunk *) _r;
  17.   unsigned long sz;
  18.  
  19. /* obscure features: realloc(NULL,n) is the same as malloc(n)
  20.  *               realloc(p, 0) is the same as free(p)
  21.  */
  22.   if (!r)
  23.     return malloc(n);
  24.   if (n == 0) {
  25.     free(_r);
  26.     return NULL;
  27.   }
  28.   p = r - 1;
  29.   sz = (n + sizeof(struct mem_chunk) + 7) & ~(7L);
  30.  
  31.   if (p->size > sz) 
  32.     {            /* block too big, split in two */
  33.     q = (struct mem_chunk * )(((long) p) + sz);
  34.     q->size = p->size - sz;
  35.         q->valid = VAL_ALLOC;
  36.     free(q + 1);
  37.     p->size = sz;
  38.     }
  39.     else 
  40.   if (p->size < sz)
  41.     {            /* block too small, get new one */
  42.     struct mem_chunk *s, *t;
  43.     q = &_mchunk_free_list;
  44.     t = _mchunk_free_list.next;
  45.     while (t != NULL && t < p)
  46.       {
  47.       q = t;
  48.       t = t->next;
  49.       }
  50.  
  51.     /* merge after if possible */
  52.     s = (struct mem_chunk * )(((long) p) + p->size);
  53.     if (t != NULL && s >= t && p->size + t->size >= sz)
  54.       {
  55.       assert(s == t);
  56.       p->size += t->size;
  57.       q->next = t->next;
  58.       t->size = 0;
  59.       t->next = NULL;
  60.       }
  61.     else
  62.       {
  63.       q = (struct mem_chunk * )malloc(n);
  64.       if (q != NULL)
  65.     {
  66.     n = p->size - sizeof(struct mem_chunk);
  67.     bcopy(r, q, n);
  68.         free(r);    /* free r only if we got a new block */
  69.         }
  70.       r = q;
  71.     }
  72.   }
  73.   /* else current block will do just fine */
  74.   return((void * )r);
  75. }
  76.  
  77. void * realloc(_r, n)
  78. void *_r;
  79. size_t n;
  80. {
  81.   return _realloc(_r, (unsigned long) n);
  82. }
  83.